// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

<template>
  <div>
    <a-spin :spinning="fetchLoading">
      <a-tabs
        :tabPosition="device === 'mobile' ? 'top' : 'left'"
        :animated="false"
        @change="onTabChange">
        <a-tab-pane
          v-for="item in hardcodedNsps"
          :key="item.title">
          <span slot="tab">
            {{ $t(item.title) }}
            <status :text="item.title in nsps ? nsps[item.title].state : $t('label.disabled')" style="margin-bottom: 6px; margin-left: 6px" />
          </span>
          <provider-item
            v-if="tabKey===item.title"
            :loading="loading"
            :itemNsp="item"
            :nsp="nsps[item.title]"
            :resourceId="resource.id"
            :zoneId="resource.zoneid"
            :tabKey="tabKey"/>
        </a-tab-pane>
      </a-tabs>
    </a-spin>
    <div v-if="showFormAction">
      <keep-alive v-if="currentAction.component">
        <a-modal
          :title="$t(currentAction.label)"
          :visible="showFormAction"
          :closable="true"
          :maskClosable="false"
          :cancelText="$t('label.cancel')"
          style="top: 20px;"
          @cancel="onCloseAction"
          :confirmLoading="actionLoading"
          :footer="null"
          centered>
          <component
            :is="currentAction.component"
            :resource="nsp"
            :action="currentAction" />
        </a-modal>
      </keep-alive>
      <a-modal
        v-else
        :title="$t(currentAction.label)"
        :visible="showFormAction"
        :confirmLoading="actionLoading"
        :maskClosable="false"
        :okText="$t('label.ok')"
        :cancelText="$t('label.cancel')"
        style="top: 20px;"
        @ok="handleSubmit"
        @cancel="onCloseAction"
        centered
      >
        <a-form
          :form="form"
          layout="vertical">
          <a-form-item
            v-for="(field, index) in currentAction.fieldParams"
            :key="index"
            :label="$t('label.' + field.name)">
            <span v-if="field.name==='password'">
              <a-input-password
                :autoFocus="index===0"
                v-decorator="[field.name, {
                  rules: [
                    {
                      required: field.required,
                      message: $t('message.error.required.input')
                    }
                  ]
                }]"
                :placeholder="field.description" />
            </span>
            <span v-else-if="field.type==='boolean'">
              <a-switch
                :autoFocus="index===0"
                v-decorator="[field.name, {
                  rules: [{
                    required: field.required,
                    message: $t('message.error.required.input')
                  }]
                }]"
                :placeholder="field.description"
              />
            </span>
            <span v-else-if="field.type==='uuid'">
              <a-select
                :autoFocus="index===0"
                v-decorator="[field.name, {
                  rules: [{
                    required: field.required,
                    message: $t('message.error.select')
                  }]
                }]"
                :loading="field.loading"
                :placeholder="field.description">
                <a-select-option
                  v-for="(opt, idx) in field.opts"
                  :key="idx">{{ opt.name || opt.description }}</a-select-option>
              </a-select>
            </span>
            <span v-else>
              <a-input
                :autoFocus="index===0"
                v-decorator="[field.name, {
                  rules: [
                    {
                      required: field.required,
                      message: $t('message.error.required.input')
                    }
                  ]
                }]"
                :placeholder="field.description" />
            </span>
          </a-form-item>
        </a-form>
      </a-modal>
    </div>
  </div>
</template>

<script>
import store from '@/store'
import { api } from '@/api'
import { mixinDevice } from '@/utils/mixin.js'
import Status from '@/components/widgets/Status'
import ProviderItem from '@/views/infra/network/providers/ProviderItem'

export default {
  name: 'ServiceProvidersTab',
  components: {
    Status,
    ProviderItem
  },
  mixins: [mixinDevice],
  props: {
    resource: {
      type: Object,
      required: true
    },
    loading: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      nsps: {},
      nsp: {},
      fetchLoading: false,
      actionLoading: false,
      showFormAction: false,
      currentAction: {},
      tabKey: 'BaremetalDhcpProvider'
    }
  },
  computed: {
    hardcodedNsps () {
      return [
        {
          title: 'BaremetalDhcpProvider',
          actions: [
            {
              api: 'addBaremetalDhcp',
              listView: true,
              icon: 'plus',
              label: 'label.add.baremetal.dhcp.device',
              args: ['url', 'username', 'password'],
              mapping: {
                dhcpservertype: {
                  value: (record) => { return 'DHCPD' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return (record && record.id && record.state === 'Enabled') },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return (record && record.id && record.state === 'Disabled') },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            },
            {
              api: 'deleteNetworkServiceProvider',
              listView: true,
              icon: 'poweroff',
              label: 'label.shutdown.provider',
              confirm: 'message.confirm.delete.provider',
              show: (record) => { return record && record.id }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist'],
          lists: [
            {
              title: 'label.baremetal.dhcp.devices',
              api: 'listBaremetalDhcp',
              mapping: {
                physicalnetworkid: {
                  value: (record) => { return record.physicalnetworkid }
                }
              },
              columns: ['url']
            }
          ]
        },
        {
          title: 'BaremetalPxeProvider',
          actions: [
            {
              api: 'addBaremetalPxeKickStartServer',
              listView: true,
              icon: 'plus',
              label: 'label.baremetal.pxe.device',
              args: ['url', 'username', 'password', 'tftpdir'],
              mapping: {
                pxeservertype: {
                  value: (record) => { return 'KICK_START' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return (record && record.id && record.state === 'Enabled') },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return (record && record.id && record.state === 'Disabled') },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            },
            {
              api: 'deleteNetworkServiceProvider',
              listView: true,
              icon: 'poweroff',
              label: 'label.shutdown.provider',
              confirm: 'message.confirm.delete.provider',
              show: (record) => { return record && record.id }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist'],
          lists: [
            {
              title: 'label.baremetal.pxe.devices',
              api: 'listBaremetalPxeServers',
              mapping: {
                physicalnetworkid: {
                  value: (record) => { return record.physicalnetworkid }
                }
              },
              columns: ['url']
            }
          ]
        },
        {
          title: 'BigSwitchBcf',
          actions: [
            {
              api: 'addBigSwitchBcfDevice',
              listView: true,
              icon: 'plus',
              label: 'label.add.bigswitchbcf.device',
              args: ['hostname', 'username', 'password', 'nat']
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return record && record.id && record.state === 'Enabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return record && record.id && record.state === 'Disabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            },
            {
              api: 'deleteNetworkServiceProvider',
              listView: true,
              icon: 'poweroff',
              label: 'label.shutdown.provider',
              confirm: 'message.confirm.delete.provider',
              show: (record) => { return record && record.id }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist'],
          lists: [
            {
              title: 'label.devices',
              api: 'listBigSwitchBcfDevices',
              mapping: {
                physicalnetworkid: {
                  value: (record) => { return record.physicalnetworkid }
                }
              },
              columns: ['hostname', 'action']
            }
          ]
        },
        {
          title: 'BrocadeVcs',
          actions: [
            {
              api: 'addBrocadeVcsDevice',
              listView: true,
              icon: 'plus',
              label: 'label.add.bigswitchbcf.device',
              args: ['hostname', 'username', 'password']
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return record && record.id && record.state === 'Enabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return record && record.id && record.state === 'Disabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            },
            {
              api: 'deleteNetworkServiceProvider',
              listView: true,
              icon: 'poweroff',
              label: 'label.shutdown.provider',
              confirm: 'message.confirm.delete.provider',
              show: (record) => { return record && record.id }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist'],
          lists: [
            {
              title: 'label.devices',
              api: 'listBrocadeVcsDevices',
              mapping: {
                physicalnetworkid: {
                  value: (record) => { return record.physicalnetworkid }
                }
              },
              columns: ['hostname', 'action']
            }
          ]
        },
        {
          title: 'CiscoVnmc',
          actions: [
            {
              api: 'addCiscoVnmcResource',
              listView: true,
              icon: 'plus',
              label: 'label.add.vnmc.device',
              args: ['hostname', 'username', 'password']
            },
            {
              api: 'addCiscoAsa1000vResource',
              listView: true,
              icon: 'plus-circle',
              label: 'label.add.ciscoasa1000v',
              args: ['hostname', 'insideportprofile', 'clusterid'],
              mapping: {
                zoneid: {
                  params: (record) => { return record.zoneid }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return record && record.id && record.state === 'Enabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return record && record.id && record.state === 'Disabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            },
            {
              api: 'deleteNetworkServiceProvider',
              listView: true,
              icon: 'poweroff',
              label: 'label.shutdown.provider',
              confirm: 'message.confirm.delete.provider',
              show: (record) => { return record && record.id }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist'],
          lists: [
            {
              title: 'label.list.ciscovnmc',
              api: 'listCiscoVnmcResources',
              mapping: {
                physicalnetworkid: {
                  value: (record) => { return record.physicalnetworkid }
                }
              },
              columns: ['resource', 'provider']
            },
            {
              title: 'label.list.ciscoasa1000v',
              api: 'listCiscoAsa1000vResources',
              mapping: {
                physicalnetworkid: {
                  value: (record) => { return record.physicalnetworkid }
                }
              },
              columns: ['hostname', 'insideportprofile', 'action']
            }
          ]
        },
        {
          title: 'ConfigDrive',
          actions: [
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return record && record.id && record.state === 'Enabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return record && record.id && record.state === 'Disabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist', 'physicalnetworkid']
        },
        {
          title: 'F5BigIp',
          actions: [
            {
              api: 'addF5LoadBalancer',
              listView: true,
              icon: 'plus',
              label: 'label.add.f5.device',
              component: () => import('@/views/infra/network/providers/AddF5LoadBalancer.vue')
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return record && record.id && record.state === 'Enabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return record && record.id && record.state === 'Disabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            },
            {
              api: 'deleteNetworkServiceProvider',
              listView: true,
              icon: 'poweroff',
              label: 'label.shutdown.provider',
              confirm: 'message.confirm.delete.provider',
              show: (record) => { return record && record.id }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist'],
          lists: [
            {
              title: 'label.devices',
              api: 'listF5LoadBalancers',
              mapping: {
                physicalnetworkid: {
                  value: (record) => { return record.physicalnetworkid }
                }
              },
              columns: ['ipaddress', 'lbdevicestate', 'action']
            }
          ]
        },
        {
          title: 'GloboDns',
          actions: [
            {
              api: 'addGloboDnsHost',
              listView: true,
              icon: 'plus',
              label: 'label.globo.dns.configuration',
              args: ['url', 'username', 'password']
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return record && record.id && record.state === 'Enabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return record && record.id && record.state === 'Disabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            },
            {
              api: 'deleteNetworkServiceProvider',
              listView: true,
              icon: 'poweroff',
              label: 'label.shutdown.provider',
              confirm: 'message.confirm.delete.provider',
              show: (record) => { return record && record.id }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist']
        },
        {
          title: 'InternalLbVm',
          actions: [
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return record && record.id && record.state === 'Enabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return record && record.id && record.state === 'Disabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            }
          ],
          details: ['name', 'state', 'id', 'physicalnetworkid', 'destinationphysicalnetworkid', 'servicelist'],
          lists: [
            {
              title: 'label.instances',
              api: 'listInternalLoadBalancerVMs',
              mapping: {
                zoneid: {
                  value: (record) => { return record.zoneid }
                }
              },
              columns: ['name', 'zonename', 'type', 'state']
            }
          ]
        },
        {
          title: 'JuniperSRX',
          actions: [
            {
              api: 'addSrxFirewall',
              listView: true,
              icon: 'plus',
              label: 'label.add.srx.device',
              component: () => import('@/views/infra/network/providers/AddSrxFirewall.vue')
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return record && record.id && record.state === 'Enabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return record && record.id && record.state === 'Disabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            },
            {
              api: 'deleteNetworkServiceProvider',
              listView: true,
              icon: 'poweroff',
              label: 'label.shutdown.provider',
              confirm: 'message.confirm.delete.provider',
              show: (record) => { return record && record.id }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist'],
          lists: [
            {
              title: 'label.devices',
              api: 'listSrxFirewalls',
              mapping: {
                physicalnetworkid: {
                  value: (record) => { return record.physicalnetworkid }
                }
              },
              columns: ['ipaddress', 'fwdevicestate', 'action']
            }
          ]
        },
        {
          title: 'Netscaler',
          actions: [
            {
              api: 'addNetscalerLoadBalancer',
              icon: 'plus',
              listView: true,
              label: 'label.add.netscaler.device',
              component: () => import('@/views/infra/network/providers/AddNetscalerLoadBalancer.vue')
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return record && record.id && record.state === 'Enabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return record && record.id && record.state === 'Disabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            },
            {
              api: 'deleteNetworkServiceProvider',
              listView: true,
              icon: 'poweroff',
              label: 'label.shutdown.provider',
              confirm: 'message.confirm.delete.provider',
              show: (record) => { return record && record.id }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist'],
          lists: [
            {
              title: 'label.devices',
              api: 'listNetscalerLoadBalancers',
              mapping: {
                physicalnetworkid: {
                  value: (record) => { return record.physicalnetworkid }
                }
              },
              columns: ['ipaddress', 'lbdevicestate', 'action']
            }
          ]
        },
        {
          title: 'NiciraNvp',
          actions: [
            {
              api: 'addNiciraNvpDevice',
              icon: 'plus',
              listView: true,
              label: 'label.add.niciranvp.device',
              component: () => import('@/views/infra/network/providers/AddNiciraNvpDevice.vue')
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return record && record.id && record.state === 'Enabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return record && record.id && record.state === 'Disabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            },
            {
              api: 'deleteNetworkServiceProvider',
              listView: true,
              icon: 'poweroff',
              label: 'label.shutdown.provider',
              confirm: 'message.confirm.delete.provider',
              show: (record) => { return record && record.id }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist'],
          lists: [
            {
              title: 'label.devices',
              api: 'listNiciraNvpDevices',
              mapping: {
                physicalnetworkid: {
                  value: (record) => { return record.physicalnetworkid }
                }
              },
              columns: ['hostname', 'transportzoneuuid', 'l3gatewayserviceuuid', 'l2gatewayserviceuuid', 'action']
            }
          ]
        },
        {
          title: 'Opendaylight',
          actions: [
            {
              api: 'addOpenDaylightController',
              listView: true,
              icon: 'plus',
              label: 'label.add.opendaylight.device',
              args: ['url', 'username', 'password']
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return record && record.id && record.state === 'Enabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return record && record.id && record.state === 'Disabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            },
            {
              api: 'deleteNetworkServiceProvider',
              listView: true,
              icon: 'poweroff',
              label: 'label.shutdown.provider',
              confirm: 'message.confirm.delete.provider',
              show: (record) => { return record && record.id }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist'],
          lists: [
            {
              title: 'label.opendaylight.controllers',
              api: 'listOpenDaylightControllers',
              mapping: {
                physicalnetworkid: {
                  value: (record) => { return record.physicalnetworkid }
                }
              },
              columns: ['name', 'url', 'username', 'action']
            }
          ]
        },
        {
          title: 'Ovs',
          details: ['name', 'state', 'id', 'servicelist'],
          lists: [
            {
              title: 'listOvsElements',
              api: 'listOvsElements',
              mapping: {
                nspid: {
                  value: (record) => { return record.id }
                }
              },
              columns: ['account', 'domain', 'enabled', 'project', 'action']
            }
          ]
        },
        {
          title: 'PaloAlto',
          actions: [
            {
              api: 'addPaloAltoFirewall',
              listView: true,
              icon: 'plus',
              label: 'label.add.pa.device',
              component: () => import('@/views/infra/network/providers/AddPaloAltoFirewall.vue')
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return (record && record.id && record.state === 'Enabled') },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return (record && record.id && record.state === 'Disabled') },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            },
            {
              api: 'deleteNetworkServiceProvider',
              listView: true,
              icon: 'poweroff',
              label: 'label.shutdown.provider',
              confirm: 'message.confirm.delete.provider',
              show: (record) => { return record && record.id }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist'],
          lists: [
            {
              title: 'label.devices',
              api: 'listPaloAltoFirewalls',
              mapping: {
                physicalnetworkid: {
                  value: (record) => { return record.physicalnetworkid }
                }
              },
              columns: ['ipaddress', 'fwdevicestate', 'type', 'action']
            }
          ]
        },
        // {
        //   title: 'SecurityGroupProvider',
        //   details: ['name', 'state', 'id', 'servicelist'],
        // },
        {
          title: 'VirtualRouter',
          actions: [
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return record && record.id && record.state === 'Enabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return record && record.id && record.state === 'Disabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist'],
          lists: [
            {
              title: 'label.instances',
              api: 'listRouters',
              mapping: {
                listAll: {
                  value: (record) => { return true }
                },
                zoneid: {
                  value: (record) => { return record.zoneid }
                },
                forvpc: {
                  value: (record) => { return false }
                }
              },
              columns: ['name', 'state', 'hostname', 'zonename']
            }
          ]
        },
        {
          title: 'VpcVirtualRouter',
          actions: [
            {
              api: 'updateNetworkServiceProvider',
              icon: 'stop',
              listView: true,
              label: 'label.disable.provider',
              confirm: 'message.confirm.disable.provider',
              show: (record) => { return record && record.id && record.state === 'Enabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Disabled' }
                }
              }
            },
            {
              api: 'updateNetworkServiceProvider',
              icon: 'play-circle',
              listView: true,
              label: 'label.enable.provider',
              confirm: 'message.confirm.enable.provider',
              show: (record) => { return record && record.id && record.state === 'Disabled' },
              mapping: {
                state: {
                  value: (record) => { return 'Enabled' }
                }
              }
            }
          ],
          details: ['name', 'state', 'id', 'servicelist'],
          lists: [
            {
              title: 'label.instances',
              api: 'listRouters',
              mapping: {
                forvpc: {
                  value: (record) => { return true }
                },
                zoneid: {
                  value: (record) => { return record.zoneid }
                },
                listAll: {
                  value: () => { return true }
                }
              },
              columns: ['name', 'state', 'hostname', 'zonename']
            }
          ]
        }
      ]
    }
  },
  beforeCreate () {
    this.form = this.$form.createForm(this)
  },
  created () {
    this.fetchData()
  },
  watch: {
    loading (newData, oldData) {
      if (!newData && this.resource.id) {
        this.fetchData()
      }
    }
  },
  inject: ['parentPollActionCompletion'],
  provide () {
    return {
      provideSetNsp: this.setNsp,
      provideExecuteAction: this.executeAction,
      provideCloseAction: this.onCloseAction,
      provideReload: this.fetchData
    }
  },
  methods: {
    fetchData () {
      if (!this.resource || !('id' in this.resource)) {
        return
      }
      this.fetchServiceProvider()
    },
    fetchServiceProvider (name) {
      this.fetchLoading = true
      api('listNetworkServiceProviders', { physicalnetworkid: this.resource.id, name: name }).then(json => {
        const sps = json.listnetworkserviceprovidersresponse.networkserviceprovider || []
        if (sps.length > 0) {
          for (const sp of sps) {
            this.nsps[sp.name] = sp
          }
        }
      }).catch(error => {
        this.$notifyError(error)
      }).finally(() => {
        this.fetchLoading = false
      })
    },
    onTabChange (tabKey) {
      this.tabKey = tabKey
    },
    setNsp (nsp) {
      this.nsp = nsp
    },
    async handleSubmit () {
      if (this.currentAction.confirm) {
        await this.executeConfirmAction()
        return
      }

      await this.form.validateFields(async (err, values) => {
        if (err) {
          return
        }
        const params = {}
        params.physicalnetworkid = this.nsp.physicalnetworkid
        for (const key in values) {
          const input = values[key]
          for (const param of this.currentAction.fieldParams) {
            if (param.name !== key) {
              continue
            }
            if (param.type === 'uuid') {
              params[key] = param.opts[input].id
            } else if (param.type === 'list') {
              params[key] = input.map(e => { return param.opts[e].id }).reduce((str, name) => { return str + ',' + name })
            } else {
              params[key] = input
            }
          }
        }
        if (this.currentAction.mapping) {
          for (const key in this.currentAction.mapping) {
            if (!this.currentAction.mapping[key].value) {
              continue
            }
            params[key] = this.currentAction.mapping[key].value(this.resource, params)
          }
        }
        this.actionLoading = true

        try {
          if (!this.nsp.id) {
            const serviceParams = {}
            serviceParams.name = this.nsp.name
            serviceParams.physicalnetworkid = this.nsp.physicalnetworkid
            const networkServiceProvider = await this.addNetworkServiceProvider(serviceParams)
            this.nsp = { ...this.nsp, ...networkServiceProvider }
          }
          params.id = this.nsp.id
          const hasJobId = await this.executeApi(this.currentAction.api, params, this.currentAction.method)
          if (!hasJobId) {
            await this.$message.success('Success')
            await this.fetchData()
          }
          this.actionLoading = false
          this.onCloseAction()
        } catch (error) {
          this.actionLoading = false
          this.$notification.error({
            message: this.$t('message.request.failed'),
            description: error
          })
        }
      })
    },
    onCloseAction () {
      this.currentAction = {}
      this.showFormAction = false
    },
    addNetworkServiceProvider (args) {
      return new Promise((resolve, reject) => {
        let message = ''
        api('addNetworkServiceProvider', args).then(async json => {
          const jobId = json.addnetworkserviceproviderresponse.jobid
          if (jobId) {
            const result = await this.pollJob(jobId)
            if (result.jobstatus === 2) {
              message = result.jobresult.errortext
              reject(message)
              return
            }
            resolve(result.jobresult.networkserviceprovider)
          }
        }).catch(error => {
          message = (error.response && error.response.headers && error.response.headers['x-description']) || error.message
          reject(message)
        })
      })
    },
    async pollJob (jobId) {
      return new Promise(resolve => {
        const asyncJobInterval = setInterval(() => {
          api('queryAsyncJobResult', { jobId }).then(async json => {
            const result = json.queryasyncjobresultresponse
            if (result.jobstatus === 0) {
              return
            }

            clearInterval(asyncJobInterval)
            resolve(result)
          })
        }, 1000)
      })
    },
    executeAction (action) {
      this.currentAction = action
      if (this.currentAction.confirm) {
        this.$confirm({
          title: this.$t('label.confirmation'),
          content: this.$t(action.confirm),
          onOk: this.handleSubmit
        })
      } else {
        this.showFormAction = true
        if (!action.component) {
          const apiParams = store.getters.apis[action.api].params || []
          this.currentAction.fieldParams = action.args.map(arg => {
            const field = apiParams.filter(param => param.name === arg)[0]
            if (field.type === 'uuid') {
              this.listFieldOpts(field)
            }
            return field
          }) || []
          if (this.currentAction.api === 'addCiscoVnmcResource') {
            this.currentAction.method = 'POST'
          }
        }
      }
    },
    listFieldOpts (field) {
      const paramName = field.name
      const params = { listall: true }
      const possibleName = 'list' + paramName.replace('ids', '').replace('id', '').toLowerCase() + 's'
      let possibleApi
      for (const api in store.getters.apis) {
        if (api.toLowerCase().startsWith(possibleName)) {
          possibleApi = api
          break
        }
      }
      if (this.currentAction.mapping) {
        Object.keys(this.currentAction.mapping).forEach(key => {
          if (this.currentAction.mapping[key].params) {
            params[key] = this.currentAction.mapping[key].params(this.resource)
          }
        })
      }
      if (!possibleApi) {
        return
      }
      field.loading = true
      field.opts = []
      api(possibleApi, params).then(json => {
        field.loading = false
        for (const obj in json) {
          if (obj.includes('response')) {
            for (const res in json[obj]) {
              if (res === 'count') {
                continue
              }
              field.opts = json[obj][res]
              this.$forceUpdate()
              break
            }
            break
          }
        }
      }).catch(error => {
        console.log(error.stack)
        field.loading = false
      })
    },
    async executeConfirmAction () {
      const params = {}
      params.id = this.nsp.id
      if (this.currentAction.mapping) {
        for (const key in this.currentAction.mapping) {
          if (!this.currentAction.mapping[key].value) {
            continue
          }
          params[key] = this.currentAction.mapping[key].value(this.resource, params)
        }
      }
      this.actionLoading = true

      try {
        const hasJobId = await this.executeApi(this.currentAction.api, params)
        if (!hasJobId) {
          await this.fetchData()
        }
        this.actionLoading = false
        this.onCloseAction()
      } catch (message) {
        this.actionLoading = false
        this.$notification.error({
          message: this.$t('message.request.failed'),
          description: message
        })
      }
    },
    executeApi (apiName, args, method) {
      return new Promise((resolve, reject) => {
        let hasJobId = false
        let message = ''
        const promise = (method === 'POST') ? api(apiName, {}, method, args) : api(apiName, args)
        promise.then(json => {
          for (const obj in json) {
            if (obj.includes('response') || obj.includes(apiName)) {
              for (const res in json[obj]) {
                if (res === 'jobid') {
                  this.$store.dispatch('AddAsyncJob', {
                    title: this.$t(this.currentAction.label),
                    jobid: json[obj][res],
                    description: this.$t(this.nsp.name),
                    status: 'progress'
                  })
                  this.parentPollActionCompletion(json[obj][res], this.currentAction)
                  hasJobId = true
                  break
                }
              }
              break
            }
          }

          resolve(hasJobId)
        }).catch(error => {
          message = (error.response && error.response.headers && error.response.headers['x-description']) || error.message
          reject(message)
        })
      })
    }
  }
}
</script>
